package com.jccfc.common;

import com.ctrip.framework.apollo.Config;
import com.jccfc.iMessageTo.IMessageTo;
import org.yaml.snakeyaml.Yaml;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.net.URL;
import java.util.*;

/**
 * @Auther: qym
 * @Date: 2020/12/28 13:56
 * @Description: message工具类
 */
public class MessageUtil {

    /**
     * @Auther: qym
     * @Description: 从apollo中获取key的值
     * @Param: apollo的config 需要获取的key
     * @Return:
     * @Date: 2020/12/31 10:37
     */
    public static String getApolloConfigProperties(Config[] configs, String propKey) {
        for (Config config : configs) {
            String property = config.getProperty(propKey, "");
            if ("".equals(property)) {
                continue;
            }
            return property;
        }
        return null;
    }

    /**
     * @Auther: qym
     * @Description: 获取自定义的配置文件message-config.properties的配置
     * @Param: 参数key
     * @Return: key 对应value
     * @Date: 2021/1/19 10:07
     */
    public static String getMessageConfigProperties(Map<String, String> propMap, String propKey) {
        String value = propMap.get(propKey);
        if ("".equals(value) || value == null) {
            return null;
        }
        return value;
    }

    /**
     * @Auther: qym
     * @Description: 解析yaml/yml配置文件
     * @Param: yaml/yml配置文件url
     * @Return:
     * @Date: 2020/12/30 10:15
     */
    public static Map praseYaml(URL url) {
        //获取apollo配置
        Yaml yaml = new Yaml();
        Map load = null;
        try {
            load = (Map) yaml.load(new FileInputStream(url.getFile()));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return load;
    }

    /**
     * @Auther: qym
     * @Description: 获取yaml中所有数据
     * @Param: load yaml解析的数据map用来储存yaml中的key value,yamlMap用来存储yaml整理后的key value
     * @Return:
     * @Date: 2021/1/19 13:32
     */
    public static void forEachYaml(Map<String, Object> load, StringBuilder ksb, Map<String, String> yamlMap) {
        //判断传入的yaml数据集是否有意义
        if (load == null || load.size() == 0) {
            return;
        }
        //借鉴图数据结构深度优先算法
        for (Map.Entry<String, Object> entry : load.entrySet()) {
            String k = entry.getKey();
            Object v = entry.getValue();
            //将key值存入StringBuilder
            StringBuilder sb = new StringBuilder(ksb);
            sb.append(k).append(".");
            //如果v为null 跳过执行
            if (v == null) {
                //此处提出去 会变成百分比执行 不提出去 大概率不执行 写两句重复的影响不大
                k = sb.toString().substring(0, sb.toString().length() - 1);
                if (!yamlMap.containsKey(k)) {
                    yamlMap.put(k, "");
                }
                continue;
            }
            //如果v是map类型则v下面还有层级结构
            if (v instanceof Map) {
                //递归处理
                forEachYaml((Map<String, Object>) v, sb, yamlMap);
            } else {
                //如果v不是map类型 则 v为某一属性的值
                k = sb.toString().substring(0, sb.toString().length() - 1);
                yamlMap.put(k, v.toString());
            }
        }
    }

    /**
     * @Auther: qym
     * @Description: 从yaml数据map中读取属性值
     * @Param: yaml数据集, propKey
     * @Return: propKey对应的配置值
     * @Date: 2020/12/30 13:53
     */
    public static Object getYamlPropertie(Map yamlMap, String propKey) {
        //yaml属性以"."分割
        String separator = ".";
        String[] separatorKeys = null;
        if (propKey.contains(separator)) {
            separatorKeys = propKey.split("\\.");
        } else {
            return yamlMap.get(propKey);
        }
        //存储yamlMap每一层的数据值
        Map<String, Map<String, Object>> finalValue = new HashMap<>();
        for (int i = 0; i < separatorKeys.length - 1; i++) {
            if (i == 0) {
                finalValue = (Map) yamlMap.get(separatorKeys[i]);
                continue;
            }
            if (finalValue == null) {
                break;
            }
            finalValue = (Map) finalValue.get(separatorKeys[i]);
        }
        //返回所需要的propKey值
        return finalValue == null ? null : finalValue.get(separatorKeys[separatorKeys.length - 1]);
    }

    /**
     * @Auther: qym
     * @Description: 解析properties配置文件
     * @Param:
     * @Return:
     * @Date: 2020/12/30 10:17
     */
    public static Map<String, String> praseProperties(String filePath) {
        Properties properties = new Properties();
        HashMap<String, String> propMap = new HashMap<>();
        try {
            BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(new File(filePath)));
            properties.load(bufferedInputStream);
            Enumeration<?> enumeration = properties.propertyNames();
            while (enumeration.hasMoreElements()) {
                String key = (String) enumeration.nextElement();
                String value = properties.getProperty(key);
                propMap.put(key, value);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return propMap;
    }

    /**
     * @Auther: qym
     * @Description: 检查iMessageTo 是否有意义
     * @Param: iMessageTo数据 clazz 数据类型
     * @Return:
     * @Date: 2021/1/6 13:43
     */
    public static boolean isPass(IMessageTo iMessageTo, Class<?> clazz) {
        if (iMessageTo != null && (iMessageTo.getClass().equals(clazz))) {
            return true;
        }
        return false;
    }

    /**
     * @Auther: qym
     * @Description: 检查iMessageTos 是否有意义
     * @Param: iMessageTos数据集 clazz 数据类型
     * @Return:
     * @Date: 2021/1/6 13:44
     */
    public static boolean isPass(List<IMessageTo> iMessageTos, Class<?> clazz) {
        if (iMessageTos == null || iMessageTos.size() == 0) {
            return false;
        }
        for (IMessageTo imt : iMessageTos) {
            if (!(imt.getClass().equals(clazz))) {
                return false;
            }
        }
        return true;
    }

    /**
     * @Auther: qym
     * @Description: 将iMessageTo数据向下转型
     * @Param:
     * @Return:
     * @Date: 2021/1/6 14:49
     */
    public static <T> T downcast(IMessageTo iMessageTo, Class<T> clazz) {
        return clazz.cast(iMessageTo);
    }

    /**
     * @Auther: qym
     * @Description: 将List<IMessageTo>数据集向下转型
     * @Param:
     * @Return:
     * @Date: 2021/1/6 14:49
     */
    public static <T> List<T> downcast(List<IMessageTo> iMessageTos, Class<T> clazz) {
        List<T> tList = new ArrayList<>();
        for (IMessageTo imt : iMessageTos) {
            tList.add(clazz.cast(imt));
        }
        return tList;
    }

}
